﻿using System;
using System.Windows.Documents;
using System.Windows;
using System.Xml;

namespace XAMLStylePad.Views
{
    public class XamlTag : Span
    {
        public XamlTag(string tagName, string tagOffet)
        {
            StylesCache.InitCache();
            TagName = tagName;

            _tagOffset = tagOffet;

            Inlines.AddRange(new Inline[]{ 
                new Run(_tagOffset),
                new Run("<"){ Style = StylesCache.cachedControlCharStyle},
                new Run(tagName){ Style = StylesCache.cachedTag },
                _attributes
            });
        }
        public void EndTag()
        {
            if(_content.Inlines.Count == 0)
            {
                //Inlines.Add(new Run("/>"){ Style = (Style)Resources["controlChar"] });
                Inlines.Add(new Run("/>") { Style = StylesCache.cachedControlCharStyle});
            }
            else
            {
                Inlines.AddRange(new Inline[]{
                    new Run(">"){ Style = StylesCache.cachedControlCharStyle },
                    //new Run(">"){ Style = (Style)Resources["controlChar"] },
                    _content
                });

                if(_content.Inlines.LastInline is LineBreak)
                    Inlines.Add(new Run(_tagOffset));

                Inlines.AddRange(new Inline[]{
                    
                    new Run("<"){ Style = StylesCache.cachedControlCharStyle},
                    new Run(TagName){ Style = StylesCache.cachedTag},
                    new Run("/>"){ Style = StylesCache.cachedControlCharStyle},
                });
                //Inlines.AddRange(new Inline[]{
                    
                //    new Run("<"){ Style = (Style)Resources["controlChar"] },
                //    new Run(TagName){ Style = (Style)Resources["tag"] },
                //    new Run("/>"){ Style = (Style)Resources["controlChar"] },
                //});
            }
        }
        public void AddContent(params Inline[] contents)
        {
            if(contents == null)
                return;
            foreach(var content in contents)
            {
                if(content is XamlAttribute)
                {
                    AddAttribute(content as XamlAttribute);
                    return;
                }

                if(_content.Inlines.Count == 0)
                    _content.Inlines.Add(new LineBreak());

                _content.Inlines.AddRange(new Inline[]{
                //new Run(_tagOffset),
                content,
                new LineBreak()
            });
            }
        }

        public void AddText(string text)
        {
            _content.Inlines.Add(new Run(text
                .Replace("<", "&lt;")
                .Replace(">", "&gt;")
                .Replace("&", "&amp;")
                .Replace("\"", "&quot;"))
                {
                    Style = (Style)Resources["text"]
                });
        }

        Span _attributes = new Span();
        Span _content = new Span();
        string _tagOffset;

        #region DependencyProperty 'TagName'
        public string TagName
        {
            get
            {
                return (string)GetValue(_TagName);
            }
            set
            {
                SetValue(_TagName, value);
            }
        }

        static DependencyProperty _TagName = DependencyProperty.Register("TagName", typeof(string), typeof(XamlTag));
        #endregion

       public static string Offset{
           get
           {
               return "   ";
           }
       }

        public void AddAttribute(XamlAttribute attr)
        {
            _attributes.Inlines.Add(attr);
        }
    }

    public class XamlAttribute: Span
    {
        public XamlAttribute(XmlAttribute xmlAttribute) : this(xmlAttribute.Name, xmlAttribute.Value)
        {
        }
        public XamlAttribute(string name, string value)
        {
            AttributeName = name
                .Replace("<", "&lt;")
                .Replace(">", "&gt;")
                .Replace("&", "&amp;")
                .Replace("\"", "&quot;");
            AttributeValue = value;
            StylesCache.InitCache();

            Inlines.AddRange(new Run[]{
                new Run(" "){Style=StylesCache.cachedControlCharStyle},
                new Run(name){Style=StylesCache.cachedAttrName},
                new Run("=\""){Style=StylesCache.cachedControlCharStyle},
                new Run(value){Style=StylesCache.cachedAttrValue},
                new Run("\""){Style=StylesCache.cachedControlCharStyle}
            });
        }

        public void addrange(string name, string value)
        {
            

            //Inlines.AddRange(new Run[]{
            //    new Run(" "){Style=(Style)Resources["controlChar"]},
            //    new Run(name){Style=(Style)Resources["attrName"]},
            //    new Run("=\""){Style=(Style)Resources["controlChar"]},
            //    new Run(value){Style=(Style)Resources["attrValue"]},
            //    new Run("\""){Style=(Style)Resources["controlChar"]}
            //});
            
        }

        #region DependencyProperty 'AttributeName'
        public string AttributeName
        {
            get
            {
                return (string)GetValue(_AttributeName);
            }
            set
            {
                SetValue(_AttributeName, value);
            }
        }

        static DependencyProperty _AttributeName = DependencyProperty.Register("AttributeName", typeof(string), typeof(XamlAttribute));
        #endregion

        #region DependencyProperty 'AttributeValue'
        public string AttributeValue
        {
            get
            {
                return (string)GetValue(_AttributeValue);
            }
            set
            {
                SetValue(_AttributeValue, value);
            }
        }

        static DependencyProperty _AttributeValue = DependencyProperty.Register("AttributeValue", typeof(string), typeof(XamlAttribute));
        #endregion
    }

    internal static class StylesCache
    {
        static ResourceDictionary _Resources;

        internal static void InitCache()
        {
            if(_Resources == null)
            {
                _Resources = new ResourceDictionary()
                {
                    Source = new Uri("Themes/AppResources.xaml", UriKind.Relative)
                };
                cachedControlCharStyle = (Style)_Resources["controlChar"];
                cachedAttrName = (Style)_Resources["attrName"];
                cachedAttrValue = (Style)_Resources["attrValue"];
                cachedTag = (Style)_Resources["tag"];
            }
        }

        internal static Style cachedControlCharStyle;
        internal static Style cachedAttrName;
        internal static Style cachedAttrValue;
        internal static Style cachedTag;
    }
}